<?php
/**
 * 支付下单service层
 * */

namespace App\Http\Services;

use App\Http\Model\FinanceDiamond;
use App\Http\Model\FinanceRechargeOrder;
use App\Http\Model\PayException;
use App\Http\Model\SystemConfig;
use App\Http\Model\UserReverify;
use App\Http\Model\UserVerify;
use App\Lib\LLRequest;
use App\Lib\Pay\Applepay\ApplePayResults;
use App\Lib\Pay\Alipay\wap\request;;
use App\Lib\xdpay;
use Illuminate\Support\Facades\Log;
use Yansongda\Pay\Pay;
use Illuminate\Support\Facades\Redis;
use App\Lib\Alipay;
use Alipay\EasySDK\Kernel\Config;

use function AlibabaCloud\Client\json;

//支付配置文件定义
const PAY_CONFIG_ALIPAY_APP = "pay_ali_app"; //支付宝APP
const PAY_CONFIG_WX_APP = "pay_wx_app_3"; //微信APP
const PAY_CONFIG_IOS = "pay_ios"; //ios
const PAY_CONFIG_ALIPAY_H5 = "pay_ali_h5"; //支付宝h5
const PAY_CONFIG_WX_H5 = "pay_wx_h5"; //微信h5
const PAY_CONFIG_WX_MP = "pay_wx_h5"; //微信公众号
const PAY_CONFIG_WX_MP = "pay_ali_wap"; //微信公众号

//一个支付类型对应的日志流水，一个支付配置对应一个流水类型，这里没有特殊需求尽量不要重复，新增配置就递增
const PAY_STREAM_TYPE = [
    PAY_CONFIG_ALIPAY_APP => 1,
    PAY_CONFIG_WX_APP => 2,
    PAY_CONFIG_IOS => 3,
    PAY_CONFIG_ALIPAY_H5 => 6,
    PAY_CONFIG_WX_H5 => 7,
    PAY_CONFIG_WX_MP => 8,
];

//根据pay_type找到对应的config_name，无特殊情况这里不用修改
const PAY_TYPE_MAP = [
    1 => PAY_CONFIG_ALIPAY_APP, //支付宝app
    2 => PAY_CONFIG_WX_APP, //微信app
    3 => PAY_CONFIG_IOS, //苹果
    6 => PAY_CONFIG_ALIPAY_H5, //支付宝h5
    7 => PAY_CONFIG_WX_H5, //微信H5
    8 => PAY_CONFIG_WX_MP, //公众号
];

const CIBN_BASEURL = 'https://openapi.cibn.cc';
const CIBN_MCHNO = '1000150071';
const CIBN_SECRET = 'qk4fb5jckh10hvi1rcniflvzjv7rb1zr';
const CIBN_SALT = 'fgjkl5436sdjg';
const WEIBAO_BASEURL = 'https://pay.baifugame.com/';
const SFT_BASEURL = 'https://pay.zhiguipay.com';
const SFT_SALT = '436fghfgywer344';
class FinancePayServices extends CommonServices
{
    protected $request;
    protected $config;
    protected $body = '钻石充值';
    private $model_finance_diamond;
    private $model_finance_recharge_order;
    protected $xdpayLib;
    private $modelUserVerify;
    private $alipayLib;

    protected $securityKey;
    protected $nowWechatBussinessKey = 'PAY:WECHAT:NOW:USE';//目前微信使用中的商户配置 string PAY:WECHAT:NOW:USE {strign}

    protected $modelSystemConfig;

    public function __construct(FinanceDiamond $financeDiamond, FinanceRechargeOrder $financeRechargeOrder)
    {
        parent::__construct();
        $this->config = config('pay');
        $this->model_finance_diamond = $financeDiamond;
        $this->model_finance_recharge_order = $financeRechargeOrder;
        $this->xdpayLib = new xdpay();
        $this->modelUserVerify = new UserVerify();
        $this->alipayLib = new Alipay();
        $this->modelSystemConfig = new SystemConfig();

    }

    //根据pay_type读取流水id，和支付配置名称
    public function getConfigByPayType($payType)
    {
        $def = [
            1 => PAY_CONFIG_ALIPAY_APP, //支付宝app
            2 => PAY_CONFIG_WX_APP, //微信app
            3 => PAY_CONFIG_IOS, //苹果
            6 => PAY_CONFIG_ALIPAY_H5, //支付宝h5
            7 => PAY_CONFIG_WX_H5, //微信H5
            8 => PAY_CONFIG_WX_MP, //公众号
        ];

        if($payType > 8){
            $result = [
                "config_name" => '', //配置文件名称
                "stream_type" => $payType, //流水类型
            ];
            return $result;
        }

        if (empty($def[$payType])) {
            return [];
        }

        if (empty(PAY_STREAM_TYPE[$def[$payType]])) {
            return [];
        }
        $configName = $def[$payType];
        //获取当前使用中的微信配置
        if($payType == 2){
            $redisWechat = Redis::get($this->nowWechatBussinessKey);
            $configName = empty($redisWechat) ? $def[$payType] : $redisWechat;
        }
        $result = [
            "config_name" => $configName, //配置文件名称
            "stream_type" => PAY_STREAM_TYPE[$def[$payType]], //流水类型
        ];

        return $result;
    }

    /**
     * @desc 微信app预下单
     * @date 2019/1/3
     * */
    public function unifiedOrderWxApp($configName, $order_info)
    {

        switch($configName){
            case 'pay_wx_app_1':
                $config = (new SystemConfig)->getPayWxApp1();
                break;
            case 'pay_wx_app_2':
                $config = (new SystemConfig)->getPayWxApp2();
                break;
            case 'pay_wx_app_3':
                $config = (new SystemConfig)->getPayWxApp3();
                break;
        }
        $config = explode(',', $config);
        $config = array_filter($config);
        // $config = $this->config[$configName];
        if (empty($config)) {
            return [];
        }
        $order = [
            'out_trade_no' => $order_info['order_sn'],
            'total_fee' => $order_info['price'],
        ];

        switch ($order_info['recharge_type'] ?? 0) {
            case 0:// 钻石
                $order['body'] = '任何扫码刷单代充都是骗局，您充值的钻石仅用于打赏消费';
                break;
            case 1:// 珍珠
                $order['body'] = '交易订单 - 金豆充值';
                break;
            default:
                break;
        }
        // //微信支付配置
        // 'pay_wx_app_1' => [
        //     'app_id' => 'wxe03f52235b51d75a',
        //     'appid' => 'wxe03f52235b51d75a',
        //     // 必填-商户号
        //     'mch_id' => '1704579200',
        //     // 必填-v2商户秘钥
        //     'key' => 'd41d8cd98f00b204e9800998ecf8427e',
        //     'notify_url' => env('APP_URL')."/finance/pay/wx_notify",
        //     'log' => [
        //         'file' => env('STORAGE_PATH').'/yansongda_pay.log',
        //         'level' => 'debug', // 设置日志级别为 debug
        //         'type' => 'single', // 单个文件
        //     ]
        // ],
        $config = [
            'app_id' => $config[0],
            'appid' => $config[0],
            'mch_id' => $config[1],
            'key' => $config[2],
            'notify_url' => env('APP_URL') . "/finance/pay/wx_notify",
            'log' => [
                'file' => env('STORAGE_PATH') . '/yansongda_pay.log',
                'level' => 'debug', // 设置日志级别为 debug
                'type' => 'single', // 单个文件
            ]
        ];
        // print_r($config);die;
        $result = Pay::wechat($config)->app($order);
        return ['wxpay' => json_decode($result->getContent(), true)];
    }

    /**
     * 微信h5支付调转
     * @param $key
     */
    public function referer($key)
    {
        $url = $this->model_finance_recharge_order->getWeixinReferer($key);
        if (empty($url)) {
            return;
        }
        echo '<script> window.location.href = "' . $url . '";</script>';
    }

    /**
     * @desc 微信h5预下单
     * @date 2019/1/3
     * */

    public function unifiedOrderWxH5($configName, $order_info)
    {
        $config = $this->config[$configName];
        if (empty($config)) {
            return false;
        }
        $order = [
            'out_trade_no' => $order_info['order_sn'],
            'total_fee' => $order_info['price'],
        ];

        switch ($order_info['recharge_type'] ?? 0) {
            case 0:// 钻石
                $order['body'] = '任何扫码刷单代充都是骗局，您充值的钻石仅用于打赏消费';
                break;
            case 1:// 珍珠
                $order['body'] = '交易订单 - 金豆充值';
                break;
            default:
                break;
        }

        $result = Pay::wechat($config)->wap($order);
        return ['h5wxpay' => $result->getTargetUrl()];
    }

    /**
     * @desc 支付宝app下单
     * @date 2019/1/3
     * */
    public function unifiedOrderAlipayApp($configName, $order_info, $method = 'app')
    {
        $config = $this->config[$configName];
        if (empty($config)) {
            return [];
        }
        $order = [
            'out_trade_no' => $order_info['order_sn'],
            'total_amount' => floatval($order_info['price']) / 100,
        ];

        switch ($order_info['recharge_type'] ?? 0) {
            case 0:// 钻石
                $order['subject'] = '交易订单 - 钻石充值';
                break;
            case 1:// 珍珠
                $order['subject'] = '交易订单 - 金豆充值';
                break;
            default:
                break;
        }

        // $isWhiteFlag = $this->model_finance_recharge_order->aliPayH5White($order_info['user_id']);
        // if (!$isWhiteFlag) {
        //     $userVerifyData = $this->modelUserVerify->getSuccess($order_info['user_id']);
        //     if (empty($userVerifyData)) {
        //         //判断用户是否首充 （首充允许充值）
        //         $pay_counts = $this->model_finance_recharge_order->getPayNumByUserId($order_info['user_id']);
        //         if ($pay_counts > 0) {
        //             return [];
        //         }
        //     } else {
        //         $order['ext_user_info'] = [
        //             'name' => $userVerifyData['idcard_name'],
        //             'cert_type' => 'IDENTITY_CARD',
        //             'cert_no' => $userVerifyData['idcard_number'],
        //             'need_check_info' => 'T',
        //         ];
        //     }


        // }

        $alipay = Pay::alipay($config)->$method($order);
        return ['alipay' => $alipay->getContent()];
    }

    /**
     * @desc 支付宝app下单
     * @date 2019/1/3
     * */
    public function orderAlipayApp($configName, $order_info, $method = 'app')
    {

//        $res = $this->alipayLib->setAlipayConfig(PAY_CONFIG_ALIPAY_APP);
//        if (!$res) {
//            return [];
//        }
        $subject = '交易订单 - 钻石充值';
        $outTradeNo = $order_info['order_sn'];
        $totalAmount = floatval($order_info['price']) / 100;
//        write_log("111pay", "alipay4444", $outTradeNo);
        $orderStr = $this->alipayLib->payment($subject, $outTradeNo, $totalAmount);

        return ['alipay' => $orderStr];
    }

    /**
     * @desc 支付宝h5下单
     * */
    public function unifiedOrderAlipayH5($configName, $order_info, $method = 'app')
    {
        $config = $this->config[$configName];
        if (empty($config)) {
            return false;
        }
        $order = [
            'out_trade_no' => $order_info['order_sn'],
            'total_amount' => floatval($order_info['price']) / 100,
        ];

        switch ($order_info['recharge_type'] ?? 0) {
            case 0:// 钻石
                $order['subject'] = '交易订单 - 钻石充值';
                break;
            case 1:// 珍珠
                $order['subject'] = '交易订单 - 金豆充值';
                break;
            default:
                break;
        }

        $isWhiteFlag = $this->model_finance_recharge_order->aliPayH5White($order_info['user_id']);
        if (!$isWhiteFlag) {
            $userVerifyData = $this->modelUserVerify->getSuccess($order_info['user_id']);
            if (empty($userVerifyData)) {
                //判断用户是否首充 （首充允许充值）
                $pay_counts = $this->model_finance_recharge_order->getPayNumByUserId($order_info['user_id']);
                if ($pay_counts > 0) {
                    return [];
                }
            } else {
                $order['ext_user_info'] = [
                    'name' => $userVerifyData['idcard_name'],
                    'cert_type' => 'IDENTITY_CARD',
                    'cert_no' => $userVerifyData['idcard_number'],
                    'need_check_info' => 'T',
                ];
            }
        }

        $alipay = Pay::alipay($config)->$method($order);
        return ['alipay' => $alipay->getContent()];

    }

    /**
     * @desc 支付宝h5下单
     * */
    public function orderAlipayH5($configName, $order_info, $method = 'app')
    {
        $res = $this->alipayLib->setAlipayConfig(PAY_CONFIG_ALIPAY_APP);
        if (!$res) {
            return [];
        }
        $subject = '交易订单 - 钻石充值';
        $outTradeNo = $order_info['order_sn'];
        $totalAmount = floatval($order_info['price']) / 100;

        $orderStr = $this->alipayLib->paymentH5($subject, $outTradeNo, $totalAmount);

        return ['alipay' => $orderStr];
    }
    /**
     * @desc 手机网站支付宝下单
     * */
    public function unifiedWapAlipayH5($configName, $order_info, $method = 'app')
    {
        $subject = '交易订单 - 钻石充值';
        $outTradeNo = $order_info['order_sn'];
        $totalAmount = floatval($order_info['price']) / 100;
        $orderStr = $this->alipayLib->paymentWap($subject, $outTradeNo, $totalAmount);
        return ['alipay' => $orderStr];
    }
    //获取用户openID
    public function getUserOpenId($configName,$code){
        $config = $this->config[$configName];
        if (empty($config)) {
            return false;
        }
        $get_token_url = 'https://api.weixin.qq.com/sns/oauth2/access_token';
        $params = [
            'appid' => $config['app_id'],
            'secret' => $config['app_secret'],
            'code' => $code,
            'grant_type' => 'authorization_code'
        ];

        $token = curl_request($get_token_url, $params, "urlencoded", "GET");
        if(!empty($token)){
            $token = json_decode($token,true);
        }

        return $token;
    }

    /**
     * 微信公众号下单
     * @param $order_info
     * @return mixed
     */
    public function unifiedOrderWxMp($configName, $order_info,$openid)
    {
        $config = $this->config[$configName];
        if (empty($config)) {
            return false;
        }


        $order = [
            'out_trade_no' => $order_info['order_sn'],
            'total_fee' => $order_info['price'],
            'openid' => $openid
        ];

        switch ($order_info['recharge_type'] ?? 0) {
            case 0:// 钻石
                $order['body'] = '交易订单 - 钻石充值';
                break;
            case 1:// 珍珠
                $order['body'] = '交易订单 - 金豆充值';
                break;
            default:
                break;
        }

        $result = Pay::wechat($config)->mp($order);

        return ['wxpay' => $result->toArray()];
    }

    /**
     * @desc 苹果内购下单
     * @date 2019/1/4
     * */
    public function unifiedOrderApple($order_info)
    {
        return $order_info;
    }


    /**
     * 支付宝通知验证
     * @return null|\Yansongda\Supports\Collection
     */
    public function alipay_notify_verify()
    {
        $alipay = Pay::alipay($this->config[PAY_TYPE_MAP[1]]);
        try {
            $data = $alipay->verify();
            return $data->toArray();
            //Log::debug('Alipay notify', $data->all());
        } catch (\Exception $e) {
            //echo $e->getMessage();
            return null;
        }
    }

    /**
     * 支付宝通知验证
     */
    public function alipayNotifyVerify($parameters)
    {
        $res = $this->alipayLib->setAlipayConfig(PAY_CONFIG_ALIPAY_APP);
        $res = $this->alipayLib->verifyNotify($parameters);
        return $res;
    }

    /**
     * 支付宝通知验证
     * @return null|\Yansongda\Supports\Collection
     */
    public function alipay_h5_notify_verify()
    {
        $alipay = Pay::alipay($this->config[PAY_TYPE_MAP[6]]);
        try {
            $data = $alipay->verify();
            return $data->toArray();
            //Log::debug('Alipay notify', $data->all());
        } catch (\Exception $e) {
            //echo $e->getMessage();
            return null;
        }
        return null;
    }

    /**
     * 支付宝通知验证H5
     */
    public function alipayH5NotifyVerify($parameters)
    {
        $res = $this->alipayLib->setAlipayConfig(PAY_CONFIG_ALIPAY_H5);
        $res = $this->alipayLib->verifyNotify($parameters);
        return $res;
    }

    /**
     * 微信公众号通知验证
     * @return null|\Yansongda\Supports\Collection
     */
    public function wxmppay_notify_verify()
    {
        $pay = Pay::wechat($this->config[PAY_TYPE_MAP[8]]);
        try {
            $data = $pay->verify();
            return $data->toArray();
            //Log::debug('Wechat notify', $data->all());
        } catch (\Exception $e) {
            //echo  $e->getMessage();
            return null;
        }
    }

    /**
     * 微信通知验证
     * @return array|null
     */
    public function wxpay_notify_verify()
    {
        $nowUse = Redis::get($this->nowWechatBussinessKey);
        if(!empty($nowUse)){
            switch ($nowUse) {
                case 'pay_wx_app_1':
                    $config = (new SystemConfig)->getPayWxApp1();
                    break;
                case 'pay_wx_app_2':
                    $config = (new SystemConfig)->getPayWxApp2();
                    break;
                case 'pay_wx_app_3':
                    $config = (new SystemConfig)->getPayWxApp3();
                    break;
            }
            $config = explode(',', $config);
            $config = array_filter($config);
            $config = ['app_id' => $config[0], 'appid' => $config[0], 'mch_id' => $config[1], 'key' => $config[2], 'notify_url' => env('APP_URL') . "/finance/pay/wx_notify"];
        }
        write_log("pay", "wxpaycallback", $config);
        $pay = Pay::wechat($config);
        try {
            $data = $pay->verify();
            return $data->toArray();
            //Log::debug('Wechat notify', $data->all());
        } catch (\Exception $e) {
            //echo  $e->getMessage();
            return null;
        }
        return null;
    }


    public function apple_notify_order($receipt_data)
    {
        $curr_user = $this->user->get_current_user();
        if (empty($curr_user)) {
            return null;
        }
        $count = $this->model_finance_recharge_order->hasAppleReceiptInc($curr_user['user_id'], $receipt_data);
        if ($count > 1) {
            write_log("applePay", "apple_notify_verify-02", $receipt_data);
            return null;
        }
        $apple_orders = ApplePayResults::get_order_info($receipt_data);
        write_log("applePay", "apple_orders", $apple_orders);

        $ret_data = [];
        foreach ($apple_orders as $order) {
            if ($order['bundle_id'] != 'com.ningjing.dada') {
                continue;
            }

            // TODO 判断钻石 与 珍珠规格 交替使用
            $rule = $this->model_finance_diamond->getDiamondRulePi($order['product_id']);
            if (empty($rule)) {
                continue;
            }

            $count = $this->model_finance_recharge_order->hasAppleTransactionIdInc($order['transaction_id']);
            if ($count > 1) {
                continue;
            }
            $order['out_order_sn'] = $order['transaction_id'] . $order['purchase_date_ms'];
            $old_order = $this->model_finance_recharge_order->getOrderByOutsn($order['out_order_sn']);
            if (!empty($old_order)) {
                continue;
            }
            $order['user_id'] = $curr_user['user_id'];
            $order['rule_id'] = $rule['rule_id'];
            $order['channel_id'] = $curr_user['channel_id'];

            // TODO 增加规则充值类型 存在钻石数量则是 0=钻石充值，否则是 1=珍珠充值
            $order['rule_recharge_type'] = isset($rule['diamond_amount']) ? 0 : 1;

            $ret_data [] = $order;
        }
        return $ret_data;
    }

    //判断用户是否需要再次认证
    public static function needReverify($userId)
    {
        $exceptionCount = (new PayException())->getExceptionCountByUserId($userId);
        if ($exceptionCount <= 0) {
            return false;
        }

        //判断是否已经二次认证了
        $userReverify = (new UserReverify())->getLatest($userId);
        $ua = LLRequest::parse_app_UA();
        //如果已经二次认证过了
        if (!empty($userReverify)) {
            if ($ua['guid'] == $userReverify['guid']) {
                return false;
            }
        }
        return true;
    }

    //判断用户是否需要再次认证 h5用 这个不判断设备号
    public static function needReverifyH5($userId)
    {
        $exceptionCount = (new PayException())->getExceptionCountByUserId($userId);
        if ($exceptionCount <= 0) {
            return false;
        }

        //判断是否已经二次认证了
        $userReverify = (new UserReverify())->getLatest($userId);
        //如果已经二次认证过了
        if (!empty($userReverify)) {
            return false;
        }
        return true;
    }

    //支付宝单日单人充值最大金额限制
    public static function getTodayRechargeTotalByPayTypeAndUserId($userId, $payTypes)
    {
        return (new FinanceRechargeOrder())->getTodayRechargeTotalByPayTypeAndUserId($userId, $payTypes);
    }

    //三方微信支付
    public function unifiedThreeWechat($order_info){
        $orderSn =  $order_info['order_sn'];
        $total = $order_info['price'];
        $userId = $order_info['user_id'];

        $payParams = [
            'order_type' => 'get_order',//固定参数
            'order_id' => $orderSn,//订单20位数字
            'order_amount' => $total/100,//单位元
            'pay_type' => 'wxPay',
            'user_id' => $userId,
            'notify' => env('APP_URL').'/finance/pay/threewx_notify',
        ];
        //加签
        $payParams['sign'] = $this->threeSignParam($payParams);
        //调用支付
        $url = 'http://hyzf.xiaochaipaidui.com/get_order';

        $res = curl_request($url, $payParams, 'urlencoded', 'POST');
        $res = json_decode($res,true);
        write_log("pay_three", "INFO wx", $res);
        if(!empty($res) && $res['status'] == 200){
            //微信特殊处理若返回https开头则替换成weixin://dl/business/?t=
            $payUrl = $res['url'];
            $strArr = parse_url($payUrl);

            if(isset($strArr['scheme']) && $strArr['scheme'] === 'https'){
                $wechatId = $strArr['path'];
                $wechatId = ltrim($wechatId,'/');
                $payUrl = 'weixin://dl/business/?t='.$wechatId;
            }
            return ['url'=>$payUrl];
        }else{
            return [];
        }
    }

    //三方支付宝
    public function unifiedThreeAliPay($order_info){
        $orderSn =  $order_info['order_sn'];
        $total = $order_info['price'];
        $userId = $order_info['user_id'];

        $payParams = [
            'order_type' => 'get_order',//固定参数
            'order_id' => $orderSn,//订单20位数字
            'order_amount' => $total/100,//单位元
            'pay_type' => 'aliPay',
            'user_id' => $userId,
            'notify' => env('APP_URL').'/finance/pay/threeali_notify',
        ];
        //加签
        $payParams['sign'] = $this->threeSignParam($payParams);
        //调用支付
        $url = 'http://hyzf.xiaochaipaidui.com/get_order';

        $res = curl_request($url, $payParams, 'urlencoded', 'POST');
        $res = json_decode($res,true);
        write_log("pay_three", "INFO ali", $res);
        if(!empty($res) && $res['status'] == 200){
            return ['url'=>$res['url']];
        }else{
            return [];
        }
    }

    //三方微信回调
    public function three_notify_check($notify){
        if($notify['returncode'] != 00){
            return false;
        }
        return true;
    }

    //三方签名规则
    public function threeSignParam($param=[]){
        if(empty($param)){
            return '';
        }
        // 对数组的值进行降序排序
        $firstArr = $param;
        krsort($firstArr);
        $str = http_build_query($firstArr);
        $str = urldecode($str);
        $md5Str6 = substr(md5($str), 8, 16); //转md5 16位
        $strtolowerStr = strtolower($md5Str6);//转为小写
        //对数据升序排序
        $secondArr = $param;
        ksort($secondArr);
        $secondArr['key'] = $strtolowerStr;

        $upStr = http_build_query($secondArr);
        $upStr = urldecode($upStr);
        $finalStr = md5($upStr);
        $finalStr = strtoupper($finalStr);
        return $finalStr;
    }

    public function getCibnConfig() {
        $config = $this->modelSystemConfig->getPayCibnConfig();
        $ret = [
            'mch_no' => $config[0] ?? '',
            'secret' => $config[1] ?? '',
        ];

        return $ret;
    }

    //cibn支付宝
    public function unifiedCibnAliPay($order_info){
        $orderSn =  $order_info['order_sn'];
        $total = $order_info['price'];

        $microtime = microtime(true);
        $millis = round($microtime * 1000);

        $payParams = [
            'version' => '1.0.0',//固定参数
            'signType' => 'MD5',//固定参数
            'mchNo' => $this->getCibnConfig()['mch_no'],// 商户号
            'reqTime' => $millis,// 请求毫秒数
            'mchOrderNo' => $orderSn,//
            'productCode' => 'ALI_APP',//
            'amount' => bcdiv($total, 100, 2),//单位元
            'currency' => 'cny',
            'clientIp' => $this->getRealIp(),
            'subject' => '充值支付',
            'body' => md5($orderSn . CIBN_SALT),
            'notifyUrl' => env('APP_URL').'/finance/pay/cibnali_notify',
            'expiredTime' => '3600',
            'payChannel' => '1',
        ];
        //加签
        $payParams['sign'] = $this->cibnSign($payParams);
        //调用支付
        $url = CIBN_BASEURL . '/api/v2/pay/order-create';

        $res = curl_request($url, $payParams, 'json', 'POST');
        $res = json_decode($res,true);
        write_log("pay_cibn", "order-create", $res);
        if(!empty($res) && $res['code'] == 200){
            return ['alipay'=>$res['data']['payData']];
        }else{
            return [];
        }
    }

    public function getRealIp()
    {
        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        return $ip;
    }

    public function cibnSign($data)
    {
        if (empty($data)) {
            return '';
        }
        ksort($data);//降序
        $queryString = '';
        foreach ($data as $key => $value) {
            $queryString .= $key . '=' . $value . '&';
        }
        // 去除最后一个"&"字符
        $queryString = rtrim($queryString, '&') . $this->getCibnConfig()['secret'];
        $sign = strtoupper(md5($queryString));

        return $sign;
    }

    //cibn支付回调
    public function cibn_notify_check($notify){
//        $notify = '{"body":"35da91c7eb4c145cb5380ca73bf8ce59","buyerAccount":"133****3749","buyerInfo":"2088122709397831","mchNo":"1000150071","merchantTradeNo":"2410081150012024100888374","payTime":1728402614000,"platformOutTradeNo":"OP24100823501843680256956035073","productCode":"ALI_APP","reqTime":"1728402615212","sign":"ae285203f5d73681c689da2624bc06e7","state":2,"totalAmount":198,"tradeNo":"2024100822001497831449046182"}';
//        $notify = json_decode($notify, true);
        if ($notify['state'] != 2) {
            return false;
        }

        if ($notify['body'] != md5($notify['merchantTradeNo'] . CIBN_SALT)) {
            return false;
        }

        $order_query = $this->cibn_query($notify['merchantTradeNo']);
        if (empty($order_query)) {
            return false;
        }

        if ($order_query['state'] != 2) {
            return false;
        }

        return true;
    }

    public function cibn_query($mchNo) {
        $microtime = microtime(true);
        $millis = round($microtime * 1000);

        $payParams = [
            'version' => '1.0.0',//固定参数
            'signType' => 'MD5',//固定参数
            'mchNo' => $this->getCibnConfig()['mch_no'],// 商户号
            'reqTime' => $millis,// 请求毫秒数
            'merchantTradeNo' => $mchNo,
        ];
        //加签
        $payParams['sign'] = $this->cibnSign($payParams);
        //调用支付
        $url = CIBN_BASEURL . '/api/v2/pay/order-query';

        $res = curl_request($url, $payParams, 'json', 'POST');
        $res = json_decode($res,true);
        write_log("pay_cibn", "order-query", $res);
        if(!empty($res) && $res['code'] == 200){
            return $res['data'];
        }else{
            return [];
        }
    }
    //微保支付
    public function unifiedweibaoAliPay($order_info){
        $orderSn =  $order_info['order_sn'];
        $total = $order_info['price'];
        $totalprice = $order_info['price']/100;
        $payParams = [
            'externalId' => $this->getWeibaoConfig()['mch_no'],// 商户号
            'merchantTradeNo' => $orderSn,//订单号
            'totalAmount' => bcdiv($total, 100, 2),//单位元
            'merchantSubject' => '甜枕充值'.$totalprice.'元', //订单标题
            'externalGoodsType' => '1', //订单标题
            'clientIp' => $this->getRealIp(),
            'merchantPayNotifyUrl' => env('APP_URL').'/finance/pay/weibaoali_notify',//商户异步通知URL
            'riskControlNotifyUrl' => env('APP_URL').'/finance/pay/weibaoali_riskControlNotifyUrl',//风控通知URL
            'quitUrl' => env('APP_URL').'/finance/pay/do',//用户付款中途退出返回商户网站的地址(typeIndex=1时必传)
            'returnUrl' => env('APP_URL').'/finance/pay/do',//支付成功同步返回地址(typeIndex=1或2时必传)
            'typeIndex' => '3',
            'payChannel' => '1',
        ];
        $aesKey=$this->getWeibaoConfig()['aes'];
        $md5Key=$this->getWeibaoConfig()['md5'];
        $timestamps = time();
        $plainText = md5($md5Key. ":" .$timestamps);
        $iv = substr($aesKey,0,16);
        $visitAuth=$this->encrypt($plainText,$aesKey,$iv);
        $httpHeader=[
            "Accept:application/json;",
            "charset:utf-8;",
            "timeStamp:".$timestamps,
            "visitAuth:".$visitAuth,
        ];
        //调用支付
        $url = WEIBAO_BASEURL . 'apiv2/payment/pay';
        $res =$this->posturl($url, $payParams, $httpHeader);
        write_log("pay_weibao", "order-create", $res);
        if(!empty($res) && $res['code'] == 0){
            return ['alipay'=>$res['data']['data']['pay_url']];
        }else{
            return [];
        }
    }

    public function getWeibaoConfig() {
        $config = $this->modelSystemConfig->getPayWeibaoConfig();
        $ret = [
            'mch_no' => $config[0] ?? '',
            'aes' => $config[1] ?? '',
            'md5' => $config[2] ?? '',
        ];

        return $ret;
    }
    /**
     * 加密
     * @param string $plainText 明文
     * @return bool|string
     */
    public function encrypt($plainText,$paystoreaes,$iv)
    {
        $originData = (openssl_encrypt($this->addPkcs7Padding($plainText, 16), 'AES-192-CBC', $paystoreaes, OPENSSL_NO_PADDING, $iv));
        return $originData === false ? false : base64_encode($originData);
    }

    /**
     * 解密
     * @param string $cipherText 密文
     * @return bool|string
     */
    public function decrypt($cipherText,$paystoreaes)
    {
        $aesKey = $paystoreaes;
        $iv = substr($aesKey,0,16);
        $str = base64_decode($cipherText);
        $data = openssl_decrypt($str, 'AES-192-CBC', $paystoreaes, OPENSSL_NO_PADDING, $iv);
        return $data === false ? false : $this->stripPKSC7Padding($data);
    }
    /**
     * 填充算法
     * @param string $source
     * @return string
     */
    private function addPKCS7Padding($source)
    {
        $source = trim($source);
        $block = 16;

        $pad = $block - (strlen($source) % $block);

        if ($pad <= $block) {
            $char = chr($pad);
            $source .= str_repeat($char, $pad);
        }
        return $source;
    }
    /**
     * 移去填充算法
     * @param string $source
     * @return string
     */
    private function stripPKSC7Padding($source)
    {
        $char = substr($source, -1);
        $num = ord($char);
        if ($num === 62) return $source;
        $source = substr($source, 0, -$num);
        return $source;
    }

    public function posturl($url,$data,$headerArray){
        // $data  = json_encode($data);
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //处理http证书问题
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);

        if (false === $output) {
            $ret = curl_errno($curl);

        }
        curl_close($curl);
        return json_decode($output,true);
    }


    public function getSftConfig() {
        $config = $this->modelSystemConfig->getPaySftConfig();
        $ret = [
            'mch_no' => $config[0] ?? '',
            'secret' => $config[1] ?? '',
        ];

        return $ret;
    }
    //盛付通支付宝
    public function unifiedSftAliPay($order_info){
        $orderSn =  $order_info['order_sn'];
        $total = $order_info['price'];

        $microtime = microtime(true);
        $millis = round($microtime * 1000);
        $payParams = [
            'amount' => $total,//单位分
            'mchOrderNo' => $orderSn,//
            'subject' => '商户收银',
            'cashierType' => 'MOVE',//支付宝
            'reqTime' => $millis,
            'body' => md5($orderSn . SFT_SALT),
            'version' => '2.0',//固定参数
            'sellerRemark' => '备注',
            'signType' => 'MD5',
            'notifyUrl' => env('APP_URL').'/finance/pay/sftali_notify',
            'currency' => 'CNY',
            'mchNo' => $this->getSftConfig()['mch_no'],// 商户号
        ];
        //加签
        $payParams['sign'] = $this->sftSign($payParams);
        //调用支付
        $url = SFT_BASEURL . '/api/v2/pay/unifiedOrder';

        $res = curl_request($url, $payParams, 'json', 'POST');
        $res = json_decode($res,true);
        write_log("pay_sft", "order-create", $res);
        if(!empty($res) && $res['code'] == 0){
            return ['url'=>$res['data']['payUrl']];//支付宝
        }else{
            return [];
        }
    }
    //盛付通微信
    public function unifiedSftWechat($order_info){
        $orderSn =  $order_info['order_sn'];
        $total = $order_info['price'];
        $microtime = microtime(true);
        $millis = round($microtime * 1000);
        $payParams = [
            'amount' => $total,//单位分
            'mchOrderNo' => $orderSn,//
            'subject' => '商户收银',
            'wxAppId' => 'wx9cc65720f5803028',
            'cashierType' => 'WX_APP',  //微信
            'reqTime' => $millis,
            'body' => md5($orderSn . SFT_SALT),
            'version' => '2.0',//固定参数
            'sellerRemark' => '备注',
            'signType' => 'MD5',
            'notifyUrl' => env('APP_URL').'/finance/pay/sftali_notify',
            'currency' => 'CNY',
            'mchNo' => $this->getSftConfig()['mch_no'],// 商户号
        ];
        //加签
        $payParams['sign'] = $this->sftSign($payParams);
        //调用支付
        $url = SFT_BASEURL . '/api/v2/pay/unifiedOrder';

        $res = curl_request($url, $payParams, 'json', 'POST');
        $res = json_decode($res,true);
        write_log("pay_sft", "order-create", $res);
        if(!empty($res) && $res['code'] == 0){
            $url=json_decode($res['data']['payUrl'],true);
            return ['url'=>$url['qrUrl']];//微信支付
        }else{
            return [];
        }
    }
    public function sftSign($data)
    {
        if (empty($data)) {
            return '';
        }
        ksort($data);
        $queryString = '';
        foreach ($data as $key => $value) {
            if (!empty($value)) {
                $queryString .= $key . '=' . $value . '&';
            }

        }
        // 去除最后一个"&"字符
        $queryString = $queryString . 'key=gxJZ2PB73gGOPq9uYTcmPQDnSGRU78JP1Z0v5hyAgde6nipJHNpxqZHjKRZkf74a0486zzwUcosnyuGs87h8fDX21NR53ruHIU2BvuTnVVWcuUboDm0XKmfPGPY588jn';
        $utf8String = mb_convert_encoding($queryString, 'UTF-8', 'auto');

        $sign = strtoupper(md5($utf8String));

        return $sign;
    }

    //cibn支付回调
    public function sft_notify_check($notify){
//        $notify = '{"body":"35da91c7eb4c145cb5380ca73bf8ce59","buyerAccount":"133****3749","buyerInfo":"2088122709397831","mchNo":"1000150071","merchantTradeNo":"2410081150012024100888374","payTime":1728402614000,"platformOutTradeNo":"OP24100823501843680256956035073","productCode":"ALI_APP","reqTime":"1728402615212","sign":"ae285203f5d73681c689da2624bc06e7","state":2,"totalAmount":198,"tradeNo":"2024100822001497831449046182"}';
//        $notify = json_decode($notify, true);
        if ($notify['state'] != 2) {
            return false;
        }

        if ($notify['body'] != md5($notify['mchOrderNo'] . SFT_SALT)) {
            return false;
        }

//        $order_query = $this->sft_query($notify['mchOrderNo'], $notify['payOrderId']);
//        if (empty($order_query)) {
//            return false;
//        }
//
//        if ($order_query['state'] != 2) {
//            return false;
//        }

        return true;
    }

    public function sft_query($mchNo, $payOrderId) {
        $microtime = microtime(true);
        $millis = round($microtime * 1000);

        $payParams = [
            'version' => '2.0',//固定参数
            'signType' => 'MD5',//固定参数
            'mchNo' => 'M1732267690',// 商户号
            'reqTime' => $millis,// 请求毫秒数
            'mchOrderNo' => $mchNo,
            'payOrderId' => $payOrderId,
        ];
        //加签
        $payParams['sign'] = $this->sftSign($payParams);
        //调用支付
        $url = SFT_BASEURL . '/api/v2/pay/query';

        $res = curl_request($url, $payParams, 'json', 'POST');
        $res = json_decode($res,true);
        write_log("pay_cibn", "order-query", $res);
        if(!empty($res) && $res['code'] == 200){
            return $res['data'];
        }else{
            return [];
        }
    }



    public function unifiedZftH5($order_info){
        $orderSn =  $order_info['order_sn'];
        $total = $order_info['price'];
        $config = $this->getZftH5Config();

        $payParams = [
            'service' =>'zft.alipay.h5' ,//接口名称
            'apikey' => $config['mch_no'],//商家APIKEY，唯一标识，由服务商提供
            'nonce_str' => md5($orderSn),//随机字符串，长度不超过32位
            'money' => bcdiv($total, 100, 2),  //支付金额
            'mch_orderid' => $orderSn,//商户订单号
            'remarks' => '订单备注',
            'notify_url' => env('APP_URL').'/finance/pay/zftH5_notify',
            'return_url' => env('APP_URL').'/finance/pay/do',
//            'good_name' =>$order_info['name'],//
        ];

        //加签
        $payParams['sign'] = $this->zftH5Sign($payParams, $config['secret']);
        write_log("pay_zftH5", "payParams", $payParams);

        //调用支付
        $url = 'https://payapi.changfu0591.top/payapi/zft/h5';

        $res = curl_request($url, $payParams, 'urlencoded', 'POST');
        $res = json_decode($res,true);

        write_log("pay_zftH5", "order-create", $res);
        if(!empty($res) && $res['status'] == 10000){
            return ['url'=>$res['url']];
        }else{
            return [];
        }
    }

    public function unifiedZftApp($order_info){
        $orderSn =  $order_info['order_sn'];
        $total = $order_info['price'];
        $config = $this->getZftAppConfig();

        $payParams = [
            'service' =>'zft.alipay.app' ,//接口名称
            'apikey' => $config['mch_no'],//商家APIKEY，唯一标识，由服务商提供
            'nonce_str' => md5($orderSn),//随机字符串，长度不超过32位
            'money' => bcdiv($total, 100, 2),  //支付金额
            'mch_orderid' => $orderSn,//商户订单号
            'remarks' => '订单备注',
            'notify_url' => env('APP_URL').'/finance/pay/zftH5_notify',
            'return_url' => env('APP_URL').'/finance/pay/do',
//            'good_name' =>$order_info['name'],//
        ];

        //加签
        $payParams['sign'] = $this->zftH5Sign($payParams, $config['secret']);
        write_log("pay_zftApp", "payParams", $payParams);

        //调用支付
        $url = 'https://payapi.changfu0591.top/payapi/zft/app';

        $res = curl_request($url, $payParams, 'urlencoded', 'POST');
        $res = json_decode($res,true);

        write_log("pay_zftApp", "order-create", $res);
        if(!empty($res) && $res['status'] == 10000){
            return ['alipay'=>$res['url']];
        }else{
            return [];
        }
    }

    public function unifiedOgw($order_info){
        try {
            $orderSn =  $order_info['order_sn'];
            $total = $order_info['price'];
//        $config = $this->getZftH5Config();

            $secret = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQClQiLCmn+IfT4lkDXM9vRvDY8WnvVbNhwfxWZfxxpjcm30jI73i3knCiGPcBQfvIas/IEBhwWBv5At/6rUsbFdZw5msbltPNMub3YFmqdYXs8Ui91cRycjNVG5k/2hTQHC13NrWujUWCT9K2PxTZADPbZQdtTDKBZEK6urA3yqb3oq8PkU5xZMbmGEPlGCVMQ7Dm2je1s3E2gjmKDp+mZxAJJ7b/C93avJ8abfbNVf/jX5tlvYooD1QsF+ZGLG+fQD7fAExmE+0UUoI47/lz4O3FZWvy0KdyPHPPytxsd/djmk0xnA3bIDkMO4XF1pG09m+T64DGJyPDB3JR5eXXDdAgMBAAECggEAVx5vXrG968FCouDMS/ogT+8Q8Lbp16TF3MXeuz0mHyjy6Em1ELDZNIh1ur02Dqj/QnB2vcxlTcokAuvWLfxi6T9r6x1kCD9ZgRBHYprt/3szpbw5/OyRqFDyfWeT/JWxCPs1oHGzbkXtcf2O2WWvNtYwp2iNrzgRzOxMuoHDFcGHSAYckN9Q1PS29SyW0lm1HXqMkhJQkCBSLlFvmyth8pbVEXoajgQu9v1kZF9ih0RzX8nJiUwQQA0+kZhskRhJpT69DkdsWHwq7ny+xNwwEtsx66rUQ9FRXZ7MFj71pFCjo62vVO3XFEJ2tfdvPszJsRlrs42P3xLKQq4CzxWKQQKBgQDfTquggSxeLO1q5FKffuyWKFF9ZwpBdIJtS5gZXsnuMpLoWhmcHoRlKhiMDvi4Lga4KNIDM+x4qK6UUm0obh9kRmg+t7dAywttL0DGJUKsht3VnQaQEcP926kC9ttsN0puGBPq0yJcTAG97sXyQvWF68GtBqbeZ1FqAsHF9/skrQKBgQC9c9l8Ll1Z2LqiXJWG+G3eAmE4UE7oQnABDknyLFRgZkHre2i4qxDFfj38YlTO+vMMWxrqslkWcYrfYpzhIxbuRw85F53GYyBurpcuS6QLzo4sJN5DP86XsLLmCKvETGoviOne81MrFJtDhb4gPAsQU7FKcsCfhVBpmXE6Q4LS8QKBgHWsOCapSx8JX8bPMHbZ5IQwFNkXPkFFyyEbD7h2ycQapG2KZSpurme86hiMHya3IlVTNW/4oajngq+oS9tdRG+L5oz+NLQRCyFrICAKLHtLyoQxbe7nXbddVE+6k+APtsoTKBO7VMT8TIKw22CRRl5e4L1z3uUd3roVX9UZmx81AoGANSNfZxNiH6dIge3SCu93cYPdXPw5ha/M1p75YrHIYNmNt8z/jHx+0cYdAMNb4kpFDbwoCphHoKHsP8fbFNLQxbisrmjPWivHlwPlZ5jTxHQFMKCOrvIgsi9fnmHkO8TrK7YNUvmQ5E59Vi0XLNdqiwPOgIE7QgMUkOn29k6lTSECgYEAjRqrsepxbj755EUw9dFXiyiS0P5LploSKCZk5RmMEwuJo9zhzWjIV9n54e7nIxWkkl7afaBrB88ATHXs8WVUnEB/mTBYMaraIjA7ekrNriEGi4fhRf8JRqaEd5p2jXLdiTKUK1sIZcfL46y9f29f69E+bxnTkFJgvuaQMjcEhtk=";

            $payParams = [
                'reqNo' =>$orderSn,
                'reqTime' => date('YmdHis'),
                'version' => '1.0.0.0',
                'openAppCode' => '820250322000000175',
                'subMerchantCode' => '620250322000000161',
                'orderAmount' => bcdiv($total, 100, 2),//单位元,
                'orderSubject' => '钻石支付',
            ];

            //加签
            $payParams['signature'] = $this->ogwSign($payParams, $secret);
            $payParams['orderBody'] = md5($orderSn);
            $payParams['notifyUrl'] =  env('APP_URL').'/finance/pay/ogw_notify';
            write_log("pay_unifiedOgw", "payParams", $payParams);

            //调用支付
            $url = 'https://trade1.cibn.cc/ph-zft-ogw/api/alipay/wapPay.htm';

            $res = $this->curl($url, $payParams, 'json', 'POST');
            write_log("pay_unifiedOgw", "order-create", $res);
            $resArr = json_decode($res,true);
            if ($resArr) {
                // 错误
                return '';
            }

            return $res;
        } catch (\Exception $e) {
            write_log("pay_unifiedOgw", "unifiedOgw", $e->getMessage());
        }

        return [];
    }

    /**
     * ogw签名
     * @param $data
     * @param $secret
     * @return string
     */
    public function ogwSign($data, $secret)
    {
        try {
            if (empty($data)) {
                return '';
            }
            $queryString = '';
            foreach ($data as $key => $value) {
                $queryString = $queryString . '|' . $value;
            }
            $queryString = trim($queryString, '|');
            $utf8String = mb_convert_encoding($queryString, 'UTF-8', 'auto');

            $sign = '';

            $private_key = "-----BEGIN PRIVATE KEY-----\n" .
                wordwrap($secret, 64, "\n", true) .
                "\n-----END PRIVATE KEY-----";

            $res=openssl_get_privatekey($private_key);
            if($res)
            {
                openssl_sign($utf8String, $sign,$res,"SHA256");
                openssl_free_key($res);
            }

            $sign = base64_encode($sign);
        } catch (\Exception $e) {
            write_log("pay_unifiedOgw", "exception", $e->getMessage());
//            exit($e->getMessage());
        }

        return $sign;

    }


    public function zftH5Sign($data, $secret)
    {
        if (empty($data)) {
            return '';
        }
        ksort($data);
        $queryString = '';
        foreach ($data as $key => $value) {
            if (!empty($value)) {
                $queryString .= $key . '=' . $value . '&';
            }
        }
        // 去除最后一个"&"字符
        $queryString = $queryString . 'signkey='.$secret;
        $utf8String = mb_convert_encoding($queryString, 'UTF-8', 'auto');
        $sign = md5($utf8String);
        return $sign;
    }

    public function getZftH5Config() {
        $config = $this->modelSystemConfig->getPayZftH5Config();
        $ret = [
            'mch_no' => $config[0] ?? '',
            'secret' => $config[1] ?? '',
        ];
        return $ret;
    }

    public function getZftAppConfig() {
        $config = $this->modelSystemConfig->getPayZftAppConfig();
        $ret = [
            'mch_no' => $config[0] ?? '',
            'secret' => $config[1] ?? '',
        ];
        return $ret;
    }

    //cibn支付回调
    public function zftH5_notify_check($notify){
//        $notify = '{"body":"35da91c7eb4c145cb5380ca73bf8ce59","buyerAccount":"133****3749","buyerInfo":"2088122709397831","mchNo":"1000150071","merchantTradeNo":"2410081150012024100888374","payTime":1728402614000,"platformOutTradeNo":"OP24100823501843680256956035073","productCode":"ALI_APP","reqTime":"1728402615212","sign":"ae285203f5d73681c689da2624bc06e7","state":2,"totalAmount":198,"tradeNo":"2024100822001497831449046182"}';
//        $notify = json_decode($notify, true);
        if ($notify['paystatus'] != 1) {
            return false;
        }

//        $order_query = $this->sft_query($notify['mchOrderNo'], $notify['payOrderId']);
//        if (empty($order_query)) {
//            return false;
//        }
//
//        if ($order_query['state'] != 2) {
//            return false;
//        }

        return true;
    }

    public function ogwH5_notify_check($notify){
        if ($notify['orderStatus'] != 1) {
            return false;
        }

        return true;
    }

    public function curl($action, $params, $contentType = 'urlencoded', $httpMethod = 'POST', $httpHeader = [])
    {
        $ch = curl_init();
        if ($httpMethod == 'POST' && $contentType == 'urlencoded') {
            $httpHeader[] = 'Content-Type:application/x-www-form-urlencoded';
            curl_setopt($ch, CURLOPT_POSTFIELDS, build_query($params));
        }
        if ($httpMethod == 'POST' && $contentType == 'json') {
            $httpHeader[] = 'Content-Type:application/json';
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
        }
        if ($httpMethod == 'POST' && $contentType == 'plain') {
            $httpHeader[] = 'Content-Type:text/plain';
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        }
        if ($httpMethod == 'GET' && $contentType == 'urlencoded') {
            $action .= strpos($action, '?') === false ? '?' : '&';
            $action .= build_query($params);
        }
        curl_setopt($ch, CURLOPT_URL, $action);
        curl_setopt($ch, CURLOPT_POST, $httpMethod == 'POST');
        curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);

        //https请求
        if (1 == strpos("$" . $action, "https://")) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }

        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//         var_dump(curl_getinfo($ch));
        $ret = curl_exec($ch);
        if (false === $ret) {
            $ret = curl_errno($ch);
        }
        curl_close($ch);
        return $ret;
    }

    /**
     * 商富通h5支付
     * @param mixed $order_info
     * @param mixed $pay_type
     * @return bool|array
     */
    public function SFTH5($order_info)
    {
        try {
            $orderNo = $order_info['order_sn'];//订单号
            $totalAmount = $order_info['price'];//金额
            $config = new SystemConfig();
            $sft_config = $config->getKeyConfig("shangfutong_h5_config");
            $sft_config = array_filter(explode("\n", $sft_config[0]));

            $appid = $sft_config[0]; //appid
            $md5secret = $sft_config[1]; //md5secret
            $storeId = $sft_config[2]; //storeId

            $version = "1.0"; // 接口版本号
            $reqTime = date("YmdHis"); // 请求时间
            $reqId = $this->generateUniqueString(); // 请求的唯一ID
            $signType = "MD5"; // 签名方式

            $notifyUrl = env('APP_URL') . "/finance/pay/shangfutong_h5_notify";
            // 构建支付参数
            $bizData = [
                'subject' => '订单支付', // 订单标题
                'body' => md5($orderNo . SFT_SALT), // 订单描述,最大256字符
                'extParam' => md5($orderNo . SFT_SALT), // 订单描述,最大256字符
                'payType' => 'ALIPAY', // 支付方式:WECHAT/ALIPAY
                'amount' => $totalAmount, // 支付金额,单位分
                'currency' => 'cny', // 货币类型
                'clientIp' => client_ip(), // 客户端IP
                'mchOrderNo' => $orderNo, // 商户订单号
                'storeId' => $storeId, // 门店ID
                'notifyUrl' => $notifyUrl, // 回调地址
            ];
            // 构建业务参数
            $params = array(
                "appId" => $appid,
                "version" => $version,
                "signType" => $signType,
                "reqTime" => $reqTime,
                "reqId" => $reqId,
                "bizData" => json_encode($bizData, JSON_UNESCAPED_UNICODE)
            );

            // 生成签名
            $sign = $this->generateSFTSign($params, $md5secret);
            $params["sign"] = $sign;

            $postUrl = 'https://pay.rscygroup.com/api/open/payment/h5pay';

            $ch = curl_init();
            // 假设接口的 URL 是以下地址，根据实际情况修改
            curl_setopt($ch, CURLOPT_URL, $postUrl);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $response = curl_exec($ch);
            $responseArr = json_decode($response, true);
            // print_r($responseArr);
            $bizData = json_decode($responseArr['bizData'], true);
            // print_r($responseArr);
            $responseRes = $bizData['payInfo']['payUrl'];
            write_log('SFT', 'shangfutong_h5 res', $responseRes);
            return ['url' => $responseRes];

        } catch (\Exception $e) {
            write_log('SFT', var_export(["ex" => $e->getMessage(), "trace" => $e->getTraceAsString()], true), []);
            return false;
        }
    }

    /**
     * 生成随机唯一字符串
     * @param int $length 字符串长度,默认32位
     * @return string
     */
    private function generateUniqueString($length = 32)
    {
        // 生成一个包含字母和数字的字符集
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $str = '';

        // 获取字符集长度
        $max = strlen($chars) - 1;

        // 循环生成随机字符
        for ($i = 0; $i < $length; $i++) {
            $str .= $chars[mt_rand(0, $max)];
        }

        // 加入时间戳使字符串更具唯一性
        $str .= time();

        // 返回md5加密后的字符串
        return md5($str);
    }

    public function generateSFTSign($params, $md5secret)
    {
        // 按照参数名ASCII码从小到大排序
        ksort($params);

        // 构建签名原文字符串
        $stringA = "";
        foreach ($params as $key => $value) {
            if (!empty($value)) {
                $stringA .= $key . "=" . $value . "&";
            }
        }
        $stringA = rtrim($stringA, "&");

        // 拼接appSecret
        $stringSignTemp = $stringA . "&appSecret=" . $md5secret;
        // print_r($stringSignTemp);
        // die;
        // MD5并转大写
        $sign = strtoupper(md5($stringSignTemp));

        return $sign;

    }

    //商福通支付回调
    public function shangfutong_h5_notify_check($notify)
    {
        if ($notify['state'] != 'TRADE_SUCCESS') {
            return false;
        }

        if ($notify['extParam'] != md5($notify['mchOrderNo'] . SFT_SALT)) {
            return false;
        }
        return true;
    }

    //杉德支付回调
    public function sandpay_sdk_notify_check($notify)
    {
        if ($notify['resultStatus'] != 'success') {
            return false;
        }

        if ($notify['mid'] != "6888804124462") {
            //error_log(":::::::::nonononon:::::::::");
            return false;
        }
        return true;
    }

    /**
     * 杉德快捷支付
     * @param $order_info
     * @return array|false
     */
    public function sendPayFast($order_info)
    {

        try {
            $path = $this->GetSendPayCertPath();
            $publickey = $this->sendPayLoadX509Cert($path["publicKeyPath"]);
            $prikey= $this->sendPayLoadPk12Cert($path["privateKeyPath"], 114514);
            $orderNo = $order_info['order_sn'];//订单号
            $totalAmount = round($order_info['price']) / 100;//金额
            $userId = $order_info['user_id'];//用户ID
            //$notifyUrl = env('APP_SAND_PAY_URL') . "/finance/pay/sendpay_fast_notify";
            $notifyList = ['http://118.178.178.166', 'http://121.43.123.31'];
            $notifyUrl = $notifyList[array_rand($notifyList)]  . "/finance/pay/sendpay_fast_notify";
            $version = "4.0.0"; // 接口版本号
            $reqTime = date('Y-m-d H:i:s'); // 请求时间
            $outRespTime = date('YmdHis');
            //通用公共报文
            $publicdata=[
                //生产
                "accessMid"     => "6888804124462",
                "timestamp"     => $reqTime,
                "version"       => $version,
                "signType"      => "RSA",
                "sign"          => "",
                "encryptType"   => "AES",   //AES加密
                "encryptKey"    => "",
                "bizData"       => ""
            ];

            $params = [
                "marketProduct" => "CSDB",
                //QZF：标准线上收款
                //CSDB：企业杉德宝
                "mid" => "6888804124462",//交易商户号
                "outOrderNo" => $orderNo,//商户订单号
                "description" => "钻石充值收款",//收款订单描述
                "goodsClass" =>"10",//收款类型10 游戏点卡装备充值购买类
                "amount" => $totalAmount,//商户订单金额
                "riskmgtInfo" => [
                    "sourceIp" => $_SERVER['SERVER_ADDR'],//交易设备的IP地址，最长45位
                ],//商户上送的风险监控信息
                "funcCodeList" => [
                    "02020004",
                ],
                "payerInfo" => [
                    "payExtra" => [
                        [
                            "funcCode" => "02020004",
                            "userId" => $userId,
                        ]
                    ],
                    "frontUrl" => "/",//支付后跳转页面
                ],
                "notifyUrl" => $notifyUrl,
                "sdCashierType" => "SDK",
                "metaOption" => "[{\"s\":\"Android\",\"n\":\"\",\"id\":\"\",\"sc\":\"\"},{\"s\":\"IOS\",\"n\":\"\",\"id\":\"\",\"sc\":\"\"}]",
                "jumpScheme" => "sandcash://scpay"
            ];
            if($publicdata['encryptType']=='AES'){
                $AESKey = $this->sendPay_aes_generate(16);
                $publicdata['bizData'] = $this->snedPayAESEncrypt($params, $AESKey);
                $publicdata['encryptKey'] = $this->snedPayRSAEncryptByPub($AESKey, $publickey);
            }
            $publicdata['sign'] = $this->sendPay_sign($publicdata['bizData'], $prikey);
            $result = $this->sendpay_http_post_json($path["url"], $publicdata);
            //var_dump($path["url"],json_encode($result,true));exit();
            //var_dump($path["url"],json_encode($params,true),json_encode($params,true),json_encode($result,true));exit();
            $arr= json_decode($result,true);
            //返回失败,直接打印错误信息
            if ($arr['respCode']=='fail'){
                write_log('SDP', var_export(["ex" => json_encode($arr,true), "trace" => json_encode($arr,true)], true), []);
                return false;
            }else{
                if($publicdata['encryptType']=='AES'){
                    $verify = $this->sendPay_verify($arr['bizData'], $arr['sign'], $publickey);
                    $decryptAESKey = $this->sendPay_RSADecryptByPri($arr['encryptKey'], $prikey);
                    $decryptPlainText = json_decode($this->sendPay_AESDecrypt($arr['bizData'], $decryptAESKey));
                    //将返回数据写入日志,生产可以删除
                    $jsondata1= json_encode($decryptPlainText);
                    $jsondata2= json_encode($params);
                    $jsondata= $jsondata1.$jsondata2;
                    write_log('SDP', 'send_pay_fast_h5 res', $jsondata);
                }
                $respon=  [
                    'verify'    => $verify==1?'验签成功!':'验签失败!',
                    'params'    => json_encode($params,JSON_UNESCAPED_UNICODE),
                    'publicdata'    => json_encode($publicdata),
                    'response'     =>  objToArray($decryptPlainText),
                    'result'     =>  $result,
                    'arr'     =>  json_encode($arr,true),
                ];
            }
            if (!empty($respon['response']['cashierUrl'])) {
                return ['url' => $respon['response']['cashierUrl']];
            }else{
                write_log('SDP', 'send_pay_fast_h5 res error', json_encode($respon, true));
                return false;
            }

        } catch (\Exception $e) {
            write_log('SDP', var_export(["ex" => $e->getMessage(), "trace" => $e->getTraceAsString()], true), []);
            return false;
        }
    }

    /**
     * 杉德微信支付
     * @param $order_info
     * @return false|void
     */
    public function sendWeChatPayFast($order_info)
    {

        try {
            $path = $this->GetSendPayCertPath();
            $publickey = $this->sendPayLoadX509Cert($path["publicKeyPath"]);
            $prikey= $this->sendPayLoadPk12Cert($path["privateKeyPath"], 114514);
            $orderNo = $order_info['order_sn'];//订单号
            $totalAmount = round($order_info['price']) / 100;//金额
            $userId = $order_info['user_id'];//用户ID
            //$notifyUrl = env('APP_SAND_PAY_URL') . "/finance/pay/sendpay_wechat_notify";
            $notifyList = ['http://118.178.178.166', 'http://121.43.123.31'];
            $notifyUrl = $notifyList[array_rand($notifyList)]  . "/finance/pay/sendpay_wechat_notify";
            $version = "4.0.0"; // 接口版本号
            $reqTime = date('Y-m-d H:i:s'); // 请求时间
            $outRespTime = date('YmdHis');
            //通用公共报文
            $publicdata=[
                //生产
                "accessMid"     => "6888804124462",
                "timestamp"     => $reqTime,
                "version"       => $version,
                "signType"      => "RSA",
                "sign"          => "",
                "encryptType"   => "AES",   //AES加密
                "encryptKey"    => "",
                "bizData"       => ""
            ];

            $params = [
                "marketProduct" => "CSDB",
                //QZF：标准线上收款
                //CSDB：企业杉德宝
                "mid" => "6888804124462",//交易商户号
                "outOrderNo" => $orderNo,//商户订单号
                "description" => "钻石充值收款",//收款订单描述
                "goodsClass" =>"10",//收款类型10 游戏点卡装备充值购买类
                "amount" => $totalAmount,//商户订单金额
                "riskmgtInfo" => [
                    "sourceIp" => $_SERVER['SERVER_ADDR'],//交易设备的IP地址，最长45位
                ],//商户上送的风险监控信息
                "funcCodeList" => [
                    "02010005",
                ],
                "payerInfo" => [
                    "payExtra" => [
                        [
                            "funcCode" => "02010005",
                            //"subAppId" => "wx10033f2b37ed5ef0",//移动应用appid 微信开放平台 wx开头
                            "subAppId" => "wx9c332f61a6282475",//移动应用appid 微信开放平台 wx开头
                            "ghOriId" => "gh_fe9d1407253b",//小程序原始id  微信公众平台 gh_开头
                            "pathUrl" => "pages/zf/index?",//拉起页面
                            "miniProgramType" => "0",//小程序版本枚举值：0：正式版1：开发版2：体验版
                        ]
                    ],
                    "frontUrl" => "/",//支付后跳转页面
                ],
                "notifyUrl" => $notifyUrl,
                "sdCashierType" => "SDK",
                "metaOption" => "[{\"s\":\"Android\",\"n\":\"\",\"id\":\"\",\"sc\":\"\"},{\"s\":\"IOS\",\"n\":\"\",\"id\":\"\",\"sc\":\"\"}]",
                "jumpScheme" => "sandcash://scpay"
            ];


            if($publicdata['encryptType']=='AES'){
                $AESKey = $this->sendPay_aes_generate(16);
                $publicdata['bizData'] = $this->snedPayAESEncrypt($params, $AESKey);
                $publicdata['encryptKey'] = $this->snedPayRSAEncryptByPub($AESKey, $publickey);
            }
            $publicdata['sign'] = $this->sendPay_sign($publicdata['bizData'], $prikey);
            $result = $this->sendpay_http_post_json($path["url"], $publicdata);
            //var_dump($path["url"],json_encode($result,true));exit();
            //var_dump($path["url"],json_encode($params,true),json_encode($params,true),json_encode($result,true));exit();
            $arr= json_decode($result,true);
            //返回失败,直接打印错误信息
            if ($arr['respCode']=='fail'){
                write_log('SDP', var_export(["ex" => json_encode($arr,true), "trace" => json_encode($arr,true)], true), []);
                return false;
            }else{
                if($publicdata['encryptType']=='AES'){
                    $verify = $this->sendPay_verify($arr['bizData'], $arr['sign'], $publickey);
                    $decryptAESKey = $this->sendPay_RSADecryptByPri($arr['encryptKey'], $prikey);
                    $decryptPlainText = json_decode($this->sendPay_AESDecrypt($arr['bizData'], $decryptAESKey));
                    //将返回数据写入日志,生产可以删除
                    $jsondata1= json_encode($decryptPlainText);
                    $jsondata2= json_encode($params);
                    $jsondata= $jsondata1.$jsondata2;
                    write_log('SDP', 'send_pay_fast_h5 res', $jsondata);
                }
                $respon=  [
                    'verify'    => $verify==1?'验签成功!':'验签失败!',
                    'params'    => json_encode($params,JSON_UNESCAPED_UNICODE),
                    'publicdata'    => json_encode($publicdata),
                    'response'     =>  objToArray($decryptPlainText),
                    'result'     =>  $result,
                    'arr'     =>  json_encode($arr,true),
                ];
            }
            if (!empty($respon['response']['cashierUrl'])) {
                return ['url' => $respon['response']['cashierUrl']];
            }else{
                write_log('SDP', 'send_pay_fast_h5 res error', json_encode($respon, true));
                return false;
            }

        } catch (\Exception $e) {
            write_log('SDP', var_export(["ex" => $e->getMessage(), "trace" => $e->getTraceAsString()], true), []);
            return false;
        }
    }

    public function sendPayByNo($no)
    {
        $path = $this->GetSendPayCertPath();
        $publickey = $this->sendPayLoadX509Cert($path["publicKeyPath"]);
        $prikey= $this->sendPayLoadPk12Cert($path["privateKeyPath"], 123456);
        //通用公共报文
        $publicdata=[
            "accessMid"     => "68888TS128331",
            "timestamp"     => date('Y-m-d H:i:s'),
            "version"       => "4.0.0",
            "signType"      => "RSA",
            "sign"          => "",
            "encryptType"   => "AES",   //AES加密
            "encryptKey"    => "",
            "bizData"       => ""
        ];

        $params =[
            "outReqTime" =>date('Y-m-d H:i:s'),
            "marketProduct" =>"QZF",
            "mid"           => "68888TS128331",
            "outOrderNo"    => $no,
            //"outOperationOrderNo"        => "CCtest69830489",  //操作订单号
            // "outPayeeOrderNo"        => "CCchild52204221"   //收款订单号
        ];

        if($publicdata['encryptType']=='AES'){
            $AESKey = $this->sendPay_aes_generate(16);
            $publicdata['bizData'] = $this->paySendAESEncrypt($params, $AESKey);   //  AES 模式
            $publicdata['encryptKey'] = $this->paySendRSAEncryptByPub($AESKey, $publickey); //  AES 模式
        }
        $publicdata['sign'] = $this->sendPay_sign($publicdata['bizData'], $prikey);
        $result = $this->sendpay_http_post_json("https://openapi-uat01.sand.com.cn/v4/sd-receipts/api/trans/trans.order.query", $publicdata);
        $arr= json_decode($result,true);

        //返回失败,直接打印错误信息
        if ($arr['respCode']=='fail'){
            var_dump($arr);
        }else {
            try {
                if ($publicdata['encryptType'] == 'AES') {
                    $verify = $this->sendPay_verify($arr['bizData'], $arr['sign'], $publickey);
                    $decryptAESKey = $this->sendPay_RSADecryptByPri($arr['encryptKey'], $prikey);
                    $decryptPlainText = json_decode($this->sendPay_AESDecrypt($arr['bizData'], $decryptAESKey));

                    if ($verify==1){
                        $verify='验签成功';
                    }else{
                        $verify='验签失败';
                    }
                    $params   = json_encode($params,JSON_UNESCAPED_UNICODE);
                    $publicdata    =json_encode($publicdata);
                    $response    =  $decryptPlainText;
                    var_dump('验签结果:'.$verify);
                    var_dump('请求参数:'.$params);
                    var_dump('公共请求参数:'.$publicdata);
                    var_dump('返回结果:',$response);
                    var_dump('返回结果1:',$result);
                }
            } catch (\Exception $e) {
                return json_encode([
                    'error' => $e->getMessage(),
                    'content' => $arr
                ]);
                exit;
            }
        }
    }


    public function GetSendPayCertPath()
    {
        return [
            "publicKeyPath" => "../cert/sendPay/sand_pro.cer",
            "privateKeyPath" => "../cert/sendPay/jm_pri.pfx",
            "url" => "https://cashapi.sandpay.com.cn/gateway/trade"
        ];
    }

    /**
     * 获取公钥
     * @param $path
     * @return mixed
     * @throws Exception
     */
    public function sendPayLoadX509Cert($path)
    {
        try {
            $file = file_get_contents($path);
            if (!$file) {
                error_log('pub_key:::111');
                throw new \Exception('loadx509Cert::file_get_contents ERROR');
            }
            $cert = chunk_split(base64_encode($file), 64, "\n");
            $cert = "-----BEGIN CERTIFICATE-----\n" . $cert . "-----END CERTIFICATE-----\n";
            $res = openssl_pkey_get_public($cert);
            $detail = openssl_pkey_get_details($res);
            openssl_free_key($res);

            if (!$detail) {
                error_log('pub_key:::2222');
                throw new \Exception('loadX509Cert::openssl_pkey_get_details ERROR');
            }

            return $detail['key'];
        } catch (\Exception $e) {
            error_log('pub_key:::3333');
            throw $e;
        }
    }

    /**
     * 获取私钥
     * @param $path
     * @param $pwd
     * @return mixed
     * @throws Exception
     */
    public function sendPayLoadPk12Cert($path, $pwd)
    {
        try {
            $file = file_get_contents($path);
            if (!$file) {
                error_log('pri_key:::111');
                throw new \Exception('loadPk12Cert::file
                        _get_contents');
            }

            if (!openssl_pkcs12_read($file, $cert, $pwd)) {
                error_log('pri_key:::222');
                throw new \Exception('loadPk12Cert::openssl_pkcs12_read ERROR');
            }
            return $cert['pkey'];
        } catch (\Exception $e) {
            error_log('pri_key:::333');
            throw $e;
        }
    }

    /**
     * 生成AESKey
     * @param $size
     * @return string
     */
    public function sendPay_aes_generate($size)
    {
        $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        $arr = array();
        for ($i = 0; $i < $size; $i++) {
            $arr[] = $str[mt_rand(0, 61)];
        }

        return implode('', $arr);
    }

    /**
     * AES加密
     * @param $plainText
     * @param $key
     * @return string
     * @throws \Exception
     */
    public function snedPayAESEncrypt($plainText, $key)
    {
        ksort($plainText);
        $plainText = json_encode($plainText,JSON_UNESCAPED_UNICODE);
        //var_dump($plainText);
        $ivlen = openssl_cipher_iv_length($cipher="AES-128-ECB");
        $iv = !$ivlen?"": openssl_random_pseudo_bytes($ivlen);
        //$iv = openssl_random_pseudo_bytes($ivlen);
        $result = openssl_encrypt($plainText, 'AES-128-ECB', $key,OPENSSL_RAW_DATA,$iv);
        //var_dump($iv);
        if (!$result) {
            throw new \Exception('报文加密错误');
        }
        return base64_encode($result);
    }

    public function snedPayRSAEncryptByPub($plainText, $puk)
    {
        if (!openssl_public_encrypt($plainText, $cipherText, $puk, OPENSSL_PKCS1_PADDING)) {
            throw new \Exception('AESKey 加密错误');
        }

        return base64_encode($cipherText);
    }

    /**
     * 私钥签名
     * @param $plainText
     * @param $path
     * @return string
     * @throws Exception
     */
    public function sendPay_sign($plainText, $path)
    {
        //$plainText = json_encode($plainText);
        try {
            $resource = openssl_pkey_get_private($path);
            $result = openssl_sign($plainText, $sign, $resource,OPENSSL_ALGO_SHA256);
            //在PHP8.0以后，即时编译（JIT）模式, 性能已经提高了90%, 你不再需要手动释放openssl_free_key()资源。
            //PHP的垃圾回收机制会自动处理这些内存管理问题。所以，你不需要担心内存占用的问题。
            openssl_free_key($resource);

            if (!$result) {
                throw new \Exception('签名出错' . $plainText);
            }

            return base64_encode($sign);
        } catch (\Exception $e) {
            throw $e;
        }
    }
    /**
     * 公钥验签
     * @param $plainText
     * @param $sign
     * @param $path
     * @return int
     * @throws Exception
     */
    public function sendPay_verify($plainText, $sign, $path)
    {
        $resource = openssl_pkey_get_public($path);
        $result = openssl_verify($plainText, base64_decode($sign), $resource,'SHA256');
        //在PHP8.0以后，即时编译（JIT）模式, 性能相比7版本,已经提高了90%, 你不再需要手动释放openssl_free_key()资源。
        //PHP的垃圾回收机制会自动处理这些内存管理问题。
        openssl_free_key($resource);

        if (!$result) {
            throw new \Exception('签名验证未通过,plainText:' . $plainText . '。sign:' . $sign, '02002');
        }

        return $result;
    }

    /**
     * 私钥解密AESKey
     * @param $cipherText
     * @param $prk
     * @return string
     * @throws Exception
     */
    public function sendPay_RSADecryptByPri($cipherText, $prk)
    {
        if (!openssl_private_decrypt(base64_decode($cipherText), $plainText, $prk, OPENSSL_PKCS1_PADDING)) {
            throw new \Exception('AESKey 解密错误');
        }

        return (string)$plainText;
    }
    /**
     * AES解密
     * @param $cipherText
     * @param $key
     * @return string
     * @throws \Exception
     */
    public function sendPay_AESDecrypt($cipherText, $key)
    {
        $result = openssl_decrypt(base64_decode($cipherText), 'AES-128-ECB', $key, 1);

        if (!$result) {
            throw new \Exception('报文解密错误', 2003);
        }

        return $result;
    }

    /**
     * 发送请求
     * @param $url
     * @param $param
     * @return bool|mixed
     * @throws Exception
     */
    public function sendpay_http_post_json($url, $param)
    {
        if (empty($url) || empty($param)) {
            return false;
        }
        //NONE模式
        if($param['encryptType']=='NONE'){
            $param['bizData']=json_decode($param['bizData']);  //字符串转对象
        }
        $param = json_encode($param,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        try {

            $ch = curl_init();//初始化curl
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            //正式环境时解开注释
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            $data = curl_exec($ch);//运行curl
            curl_close($ch);

            if (!$data) {
                throw new \Exception('请求出错');
            }
            return $data;
        } catch (\Exception $e) {
            throw $e;
        }
    }

    /**
     * AES加密
     * @param $plainText
     * @param $key
     * @return string
     * @throws \Exception
     */
    public function paySendAESEncrypt($plainText, $key)
    {
        ksort($plainText);
        $plainText = json_encode($plainText,JSON_UNESCAPED_UNICODE);
        //var_dump($plainText);
        $ivlen = openssl_cipher_iv_length($cipher="AES-128-ECB");
        $iv = !$ivlen?"": openssl_random_pseudo_bytes($ivlen);
        //$iv = openssl_random_pseudo_bytes($ivlen);
        $result = openssl_encrypt($plainText, 'AES-128-ECB', $key,OPENSSL_RAW_DATA,$iv);
        //var_dump($iv);
        if (!$result) {
            throw new \Exception('报文加密错误');
        }
        return base64_encode($result);
    }

    function paySendRSAEncryptByPub($plainText, $puk)
    {
        if (!openssl_public_encrypt($plainText, $cipherText, $puk, OPENSSL_PKCS1_PADDING)) {
            throw new \Exception('AESKey 加密错误');
        }

        return base64_encode($cipherText);
    }


}
